package cn.song.freight.controller;

import cn.song.freight.annotation.OperationLog;
import cn.song.freight.domain.dto.BaseIdDTO;
import cn.song.freight.domain.dto.BaseStatusUpdateDTO;
import cn.song.freight.domain.dto.BatchDeleteStrategyAssignmentDTO;
import cn.song.freight.domain.dto.BatchStrategyAssignmentDTO;
import cn.song.freight.domain.dto.StrategyAssignmentDTO;
import cn.song.freight.domain.query.StrategyAssignmentQuery;
import cn.song.freight.domain.entity.StrategyAssignmentDO;
import cn.song.freight.domain.result.R;
import cn.song.freight.enums.ModuleType;
import cn.song.freight.enums.OperationType;
import cn.song.freight.service.StrategyAssignmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;

/**
 * 运费策略分配管理控制器
 * <pre>
 * 该控制器是运费计算系统中的核心组件之一，负责管理运费策略与业务实体的关联关系。
 * 通过策略分配功能，系统可以实现灵活的运费策略管理，支持为不同的业务场景配置差异化的计费规则。
 *
 * 主要功能：
 * 1. 策略分配管理：将运费策略分配给特定的仓库和物流公司组合
 * 2. 分配列表查询：支持按多种条件查询已分配的策略关系，便于管理和监控
 * 3. 状态管理：支持策略分配的启用/禁用操作，灵活控制策略的生效状态
 * 4. 批量操作：支持批量分配和批量删除功能，提高配置效率
 *
 * @author SongRenShuo
 * @version 3.0.0
 * @since 2025-08-27
 * </pre>
 */
@Slf4j
@Api(tags = "运费策略分配管理")
@Validated
@RequestMapping("/strategy-assignment")
@RestController
@RequiredArgsConstructor
public class StrategyAssignmentController {

    private final StrategyAssignmentService strategyAssignmentService;

    /**
     * 运费策略分配接口
     * <pre>
     * 将指定的运费策略分配给特定的仓库和物流公司组合。
     * 这是策略生效的必要步骤，只有分配后的策略才能在运费计算中被使用。
     *
     * @param strategyAssignmentDTO 运费策略分配信息对象
     * @return 分配操作结果，true表示分配成功
     * </pre>
     */
    @PostMapping("/assign")
    @ApiOperation(value = "运费策略分配", notes = "将运费策略分配给指定的仓库和物流公司组合")
    @OperationLog(
            moduleType = ModuleType.STRATEGY_ASSIGNMENT,
            operationType = OperationType.INSERT,
            description = "运费策略分配",
            businessIdField = "strategyId"
    )
    public R<Boolean> assignStrategy(@RequestBody @Valid StrategyAssignmentDTO strategyAssignmentDTO) {
        return strategyAssignmentService.assignStrategy(strategyAssignmentDTO);
    }

    /**
     * 查询运费策略分配列表
     * <pre>
     * 根据查询条件获取策略分配的列表信息，支持多种组合条件的精确查询。
     *
     * @param query 查询条件对象，支持多个可选条件的组合
     * @return 符合条件的策略分配列表
     * </pre>
     */
    @PostMapping("/list")
    @ApiOperation(value = "查询策略分配列表", notes = "根据条件查询策略分配关系")
    public R<List<StrategyAssignmentDO>> getStrategyAssignments(@RequestBody @Valid StrategyAssignmentQuery query) {
        return strategyAssignmentService.getStrategyAssignments(query);
    }

    /**
     * 修改运费策略分配状态
     * <pre>
     * 更新指定分配关系的状态，支持启用/禁用切换。状态控制着策略是否能在运费计算中被使用。
     *
     * @param statusUpdateDTO 状态更新请求对象，包含分配ID和目标状态
     * @return 状态更新结果
     * </pre>
     */
    @PostMapping("/update-status")
    @ApiOperation(value = "修改策略分配状态", notes = "更新分配关系的启用/禁用状态")
    @OperationLog(
            moduleType = ModuleType.STRATEGY_ASSIGNMENT,
            operationType = OperationType.UPDATE,
            description = "修改策略分配状态",
            businessIdField = "id"
    )
    public R<Boolean> updateStrategyAssignmentStatus(@Valid @RequestBody BaseStatusUpdateDTO statusUpdateDTO) {
        return strategyAssignmentService.updateStrategyAssignmentStatus(statusUpdateDTO.getId(), statusUpdateDTO.getStatus());
    }

    /**
     * 批量运费策略分配
     * <pre>
     * 同时为多个仓库和物流公司组合分配相同的运费策略，提高批量配置效率。
     * 该接口支持事务性操作，全部成功或全部失败。
     *
     * @param batchDTO 批量分配信息对象，包含策略ID和目标组合列表
     * @return 成功分配的数量
     * </pre>
     */
    @PostMapping("/batch-assign")
    @ApiOperation(value = "批量运费策略分配", notes = "批量为多个组合分配相同的运费策略")
    @OperationLog(
            moduleType = ModuleType.STRATEGY_ASSIGNMENT,
            operationType = OperationType.BATCH_INSERT,
            description = "批量运费策略分配",
            businessIdField = "strategyId"
    )
    public R<Integer> batchAssignStrategy(@RequestBody @Valid BatchStrategyAssignmentDTO batchDTO) {
        // 设置默认操作人（实际项目中应从当前登录用户获取）
        if (batchDTO.getOperator() == null || batchDTO.getOperator().isEmpty()) {
            batchDTO.setOperator("admin");
        }
        return strategyAssignmentService.batchAssignStrategy(batchDTO);
    }

    /**
     * 删除单个策略分配
     * <pre>
     * 删除指定的策略分配关系，适用于精确删除某个特定的分配关系。
     * 删除后该组合不再使用对应的运费策略。
     *
     * @param deleteDTO 删除请求对象，包含要删除的分配ID
     * @return 删除操作结果
     * </pre>
     */
    @PostMapping("/delete")
    @ApiOperation(value = "删除单个策略分配", notes = "删除指定的策略分配关系")
    @OperationLog(
            moduleType = ModuleType.STRATEGY_ASSIGNMENT,
            operationType = OperationType.DELETE,
            description = "删除单个策略分配",
            businessIdField = "id"
    )
    public R<Boolean> deleteStrategyAssignment(@Valid @RequestBody BaseIdDTO deleteDTO) {
        return strategyAssignmentService.deleteStrategyAssignment(deleteDTO.getId());
    }

    /**
     * 批量删除策略分配
     * <pre>
     * 同时删除多个策略分配关系，提高批量管理效率。
     * 该操作不可逆，请谨慎使用。建议在删除前确认相关策略不再被使用。
     *
     * @param batchDeleteDTO 批量删除请求对象，包含要删除的分配ID列表
     * @return 成功删除的数量
     * </pre>
     */
    @PostMapping("/batch-delete")
    @ApiOperation(value = "批量删除策略分配", notes = "批量删除多个策略分配关系")
    @OperationLog(
            moduleType = ModuleType.STRATEGY_ASSIGNMENT,
            operationType = OperationType.BATCH_DELETE,
            description = "批量删除策略分配",
            businessIdField = "ids"
    )
    public R<Integer> batchDeleteStrategy(@RequestBody @Valid BatchDeleteStrategyAssignmentDTO batchDeleteDTO) {
            // 设置默认操作人（实际项目中应从当前登录用户获取）
            if (batchDeleteDTO.getOperator() == null || batchDeleteDTO.getOperator().isEmpty()) {
                batchDeleteDTO.setOperator("admin");
            }

            // 日志记录请求信息
            log.info("批量删除请求: {}条记录", batchDeleteDTO.getIds() != null ? batchDeleteDTO.getIds().size() : 0);

            return strategyAssignmentService.batchDeleteStrategy(batchDeleteDTO);
    }
}
